//
//  GLBadgeLabel.m
//  KTools
//
//  Created by zhiyong.kuang on 2017/9/22.
//  Copyright © 2017年 zhiyong.kuang. All rights reserved.
//
//                            _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                            O\ = /O
//                        ____/`---'\____
//                      .   ' \\| |// `.
//                       / \\||| : |||// \
//                     / _||||| -:- |||||- \
//                       | | \\\ - /// | |
//                     | \_| ''\---/'' | |
//                      \ .-\__ `-` ___/-. /
//                   ___`. .' /--.--\ `. . __
//                ."" '< `.___\_<|>_/___.' >'"".
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |
//                 \ \ `-. \_ __\ /__ _/ .-` / /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//
//         .............................................
//                  佛祖镇楼                  BUG辟易



#import "GLBadgeLabel.h"
#import <objc/runtime.h>
#import <Masonry/Masonry.h>

#define GLBadgeCenterValueKey @"_value"
#define GLBadgeCenterObserverKey @"_observer"


@interface GLBadgeCenter ()
@property(nonatomic,strong)NSMutableDictionary* routers;
@end

@implementation GLBadgeCenter
+(instancetype)defaultCenter{
    static dispatch_once_t onceToken;
    static GLBadgeCenter* staticBadgeCenter;
    dispatch_once(&onceToken, ^{
        staticBadgeCenter = [[GLBadgeCenter alloc]init];
    });
    return staticBadgeCenter;
}
-(NSUInteger)badgeValueForKeyPath:(NSString*)keyPath{
    NSMutableDictionary* subRouter = [self routerForKeyPath:keyPath];
    NSNumber* valueNumber = subRouter[GLBadgeCenterValueKey];
    NSUInteger value = 0;
    if (valueNumber) {
        value = [valueNumber integerValue];
    }
    return value;
}

-(void)setBadgeValue:(NSUInteger)value forKeyPath:(NSString*)keyPath{
    
    NSString* curPath = keyPath;
    NSMutableDictionary* subRouter = [self routerForKeyPath:curPath];
    [subRouter setValue:[NSNumber numberWithInteger:value] forKeyPath:GLBadgeCenterValueKey];
    [self notifierObserverByKeyPath:curPath];
    
    curPath = [self keyPathByDeleteLastPath:curPath];
    
    while (curPath) {
        subRouter = [self routerForKeyPath:curPath];
        
        NSInteger sum = [self sumOfSubRouters:subRouter];
        
        [subRouter setValue:[NSNumber numberWithInteger:sum] forKeyPath:GLBadgeCenterValueKey];
        
        [self notifierObserverByKeyPath:curPath];
        
        curPath = [self keyPathByDeleteLastPath:curPath];
    }

    
}

-(void)registerObserver:(GLBadgeLabel*)label forKeyPath:(NSString*)keyPath{

    NSMutableDictionary* subRouter = [self routerForKeyPath:keyPath];
    NSHashTable* observers = [self observerForRouter:subRouter];

    if (![observers containsObject:label]) {
        [observers addObject:label];
    }
    NSInteger value = [self badgeValueForKeyPath:keyPath];
    [label configValue:[NSNumber numberWithInteger:value]];

}

-(void)removeObserver:(GLBadgeLabel*)label forKeyPath:(NSString*)keypath{
    NSMutableDictionary* subRouter = [self routerForKeyPath:keypath];
    NSHashTable* observers = [self observerForRouter:subRouter];

    if ([observers containsObject:label]) {
        [observers removeObject:label];
    }
}

-(NSMutableDictionary*)routerForKeyPath:(NSString*)keyPath{
    NSArray* keys = [self keysForKeyPath:keyPath];
    
    NSMutableDictionary* subRouter = self.routers;
    for (NSString* key in keys) {
        if (!subRouter[key]) {
            subRouter[key] = [NSMutableDictionary dictionaryWithCapacity:0];
        }
        subRouter = subRouter[key];
        
    }
    return subRouter;
}

-(NSArray*)keysForKeyPath:(NSString*)keyPath{
    NSArray* datas = [keyPath componentsSeparatedByString:@"."];
    return datas;
}

-(NSHashTable*)observerForRouter:(NSMutableDictionary*)router{
    if (!router[GLBadgeCenterObserverKey]) {
        router[GLBadgeCenterObserverKey] = [NSHashTable weakObjectsHashTable];
    }
    
    return router[GLBadgeCenterObserverKey];
}

-(void)notifierObserverByKeyPath:(NSString*)keyPath{
    NSMutableDictionary* subRouter = [self routerForKeyPath:keyPath];
    NSNumber* number = subRouter[GLBadgeCenterValueKey];
    
    NSHashTable* observers = subRouter[GLBadgeCenterObserverKey];
    
    NSEnumerator* enumerator = [observers objectEnumerator];
    GLBadgeLabel* label = nil;
    while (label = [enumerator nextObject])
    {
        [label configValue:number];
        
    }
    
}



-(NSInteger)sumOfSubRouters:(NSMutableDictionary*)routers{
    NSInteger sum = 0;

    NSArray* keys = [routers allKeys];
    
    for (NSString* key in keys) {
        if ([key isEqualToString:GLBadgeCenterValueKey] || [key isEqualToString:GLBadgeCenterObserverKey]) {
            continue;
        }
        
        NSMutableDictionary* subDict = routers[key];
        NSNumber* number = subDict[GLBadgeCenterValueKey];
        if (number) {
            sum+=[number integerValue];
        }
    }
    return sum;
}

-(NSString*)keyPathByDeleteLastPath:(NSString*)keyPath{
    if ([keyPath rangeOfString:@"."].location == NSNotFound) {
        return nil;
    }
    NSRegularExpression* reg = [NSRegularExpression regularExpressionWithPattern:@"\\." options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray* results = [reg matchesInString:keyPath options:NSMatchingReportCompletion range:NSMakeRange(0, keyPath.length)];
    NSTextCheckingResult* result = [results lastObject];
    if (result) {
        return [keyPath substringToIndex:result.range.location];
    }
    return nil;
}

#pragma mark- setter and getter
-(NSMutableDictionary*)routers{
    if (!_routers) {
        _routers = [NSMutableDictionary dictionaryWithCapacity:0];
    }
    return _routers;
}

@end

CGFloat distanceBetweenPoints (CGPoint p1, CGPoint p2) {
    CGFloat deltaX = p2.x - p1.x;
    CGFloat deltaY = p2.y - p1.y;
    return sqrt(deltaX*deltaX + deltaY*deltaY);
};

@implementation GLBadgeItem

-(instancetype)init{
    self = [super init];
    if (self) {
        self.backgroundColor = [UIColor redColor];
        self.color = [UIColor whiteColor];
        self.defaultString = @"NEW";
        self.style = 0;
        self.centerOffset = CGPointZero;
    }
    return self;
}
@end


@interface GLBadgeLabel(){
    BOOL _shouldUpdateSize;
}

@end
@implementation GLBadgeLabel

@synthesize edgeInsets;

#pragma mark- tools
+(NSAttributedString*)attributedStringByImage:(UIImage*)image bounds:(CGRect)bounds{
    NSTextAttachment* attachment = [[NSTextAttachment alloc]init];
    attachment.image = image;
    attachment.bounds = bounds;
    return [NSAttributedString attributedStringWithAttachment:attachment];
}


//下面三个方法用来初始化edgeInsets

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        [self configDefault];
    }
    return self;
}

- (void)awakeFromNib
{
    [super awakeFromNib];
    [self configDefault];
}


-(void)dealloc{
    NSLog(@"badge-dealloc");
    self.bindKeyPath = nil;
}


- (id)initWithFrame:(CGRect)frame

{
    
    self = [super initWithFrame:frame];
    
    if (self) {
        
        [self configDefault];
    }
    
    return self;
    
}


-(void)setFont:(UIFont *)font{
    [super setFont:font];
    self.edgeInsets = UIEdgeInsetsMake(2, font.pointSize/2.0, 2, font.pointSize/2.0);
}

-(NSString*)stringByValue:(id)value{
    
    if ([value isKindOfClass:[NSString class]]) {
        return value;
    }
    if ([value isKindOfClass:[NSNumber class]] ||
        [value isKindOfClass:[NSValue class]]) {
        if ([value integerValue] == 0) {
            return nil;
        }
        return [value stringValue];
    }
    return nil;
}
-(void)configValue:(id)value{
    
    NSString* strValue = [self stringByValue:value];
    if (!strValue) {
        self.hidden = YES;
        return;
    }
    if (self.hidden) {
        self.hidden = NO;
    }
    
    switch (self.style) {
        case GLBadgeStyleNum:
        {
            if ([strValue integerValue] > 99) {
                strValue = @"99";
            }
            if (![self.text isEqualToString:strValue]) {
                self.text = strValue;
                _shouldUpdateSize = YES;
            }
            [self.superview bringSubviewToFront:self];
            break;
        }
        case GLBadgeStyleNumMore:
        {
            if ([strValue integerValue] > 99) {
                strValue = @"99+";
            }
            if (![self.text isEqualToString:strValue]) {
                self.text = strValue;
                _shouldUpdateSize = YES;
            }
            [self.superview bringSubviewToFront:self];
            break;
        }
        case GLBadgeStyleDot:
        {
            strValue = @"";
            if (![self.text isEqualToString:strValue]) {
                self.text = strValue;
                _shouldUpdateSize = YES;
            }
            [self.superview bringSubviewToFront:self];
            break;
        }
        case GLBadgeStyleString:
        {
            if (self.defaultAttributedString) {
                if (![self.attributedText isEqualToAttributedString:self.defaultAttributedString]) {
                    self.attributedText = self.defaultAttributedString;
                    _shouldUpdateSize = YES;
                }
            }else{
                if (![self.text isEqualToString:self.defaultString]) {
                    self.text = self.defaultString;
                    _shouldUpdateSize = YES;
                }
            }
            [self.superview bringSubviewToFront:self];
            break;
        }
        case GLBadgeStyleStringCustom:
        {
            if (self.defaultAttributedString) {
                if (![self.attributedText isEqualToAttributedString:self.defaultAttributedString]) {
                    self.attributedText = self.defaultAttributedString;
                    _shouldUpdateSize = YES;
                }
            }else{
                if (![self.text isEqualToString:self.defaultString]) {
                    self.text = self.defaultString;
                    _shouldUpdateSize = YES;
                }
            }
            self.backgroundColor = [UIColor clearColor];
            [self.superview bringSubviewToFront:self];
            
            break;
        }
        default:
        {
            if (![self.text isEqualToString:strValue]) {
                self.text = strValue;
                _shouldUpdateSize = YES;
            }
            [self.superview bringSubviewToFront:self];
            break;
        }
    }
    [self updatePosition];
    
}

-(void)configDefault{
    self.cornerRadius = -1;
    self.defaultString = @"NEW";
    self.style = 0;
    self.edgeInsets = UIEdgeInsetsMake(5, 6, 5, 6);
    self.backgroundColor = [UIColor redColor];
    self.textAlignment = NSTextAlignmentCenter;
    self.textColor = [UIColor whiteColor];
    self.clipsToBounds = YES;
    self.contentMode = UIViewContentModeCenter;
}

-(void)layoutSubviews{
    [super layoutSubviews];
    if (self.style != GLBadgeStyleStringCustom) {
        [self configCornerRadius];
    }
    
}

-(void)configCornerRadius{
    if (self.hidden) {
        return;
    }
    if (self.cornerRadius >= 0) {
        self.layer.cornerRadius = self.cornerRadius;
    }else{
        self.layer.cornerRadius = self.bounds.size.height/2.0;
    }
}

// 修改绘制文字的区域，edgeInsets增加bounds
-(CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
    if (self.style == GLBadgeStyleDot) {
        self.edgeInsets = UIEdgeInsetsMake(2, 2, 2, 2);
    }
    /*
     调用父类该方法
     注意传入的UIEdgeInsetsInsetRect(bounds, self.edgeInsets),bounds是真正的绘图区域
     */
    CGRect rect = [super textRectForBounds:UIEdgeInsetsInsetRect(bounds,self.edgeInsets) limitedToNumberOfLines:numberOfLines];
    //根据edgeInsets，修改绘制文字的bounds
    rect.origin.x -= self.edgeInsets.left;
    rect.origin.y -= self.edgeInsets.top;
    rect.size.width += self.edgeInsets.left + self.edgeInsets.right;
    rect.size.height += self.edgeInsets.top + self.edgeInsets.bottom;
    return rect;
}


- (void)drawRect:(CGRect)rect

{
    if (self.style == GLBadgeStyleDot) {
        self.edgeInsets = UIEdgeInsetsMake(2, 2, 2, 2);
    }
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
    
}


- (UIBezierPath* )bezierPathWithFromPoint:(CGPoint)fromPoint
                                  toPoint:(CGPoint)toPoint
                               fromRadius:(CGFloat)fromRadius
                                 toRadius:(CGFloat)toRadius scale:(CGFloat)scale{
    
    if (isnan(fromRadius) || isnan(toRadius)||isnan(fromRadius)||isnan(toRadius)) return nil;
    
    UIBezierPath* path = [[UIBezierPath alloc] init];
    CGFloat r = distanceBetweenPoints(fromPoint, toPoint);
    CGFloat offsetY = fabs(fromRadius-toRadius);
    if (r <= offsetY) {
        CGPoint center;
        CGFloat radius;
        if (fromRadius >= toRadius) {
            center = fromPoint;
            radius = fromRadius;
        } else {
            center = toPoint;
            radius = toRadius;
        }
        [path addArcWithCenter:center radius:radius startAngle:0 endAngle:2*M_PI clockwise:YES];
    } else {
        CGFloat originX = toPoint.x - fromPoint.x;
        CGFloat originY = toPoint.y - fromPoint.y;
        
        CGFloat fromOriginAngel = (originX >= 0)?atan(originY/originX):(atan(originY/originX)+M_PI);
        CGFloat fromOffsetAngel = (fromRadius >= toRadius)?acos(offsetY/r):(M_PI-acos(offsetY/r));
        CGFloat fromStartAngel = fromOriginAngel + fromOffsetAngel;
        CGFloat fromEndAngel = fromOriginAngel - fromOffsetAngel;
        
        CGPoint fromStartPoint = CGPointMake(fromPoint.x+cos(fromStartAngel)*fromRadius, fromPoint.y+sin(fromStartAngel)*fromRadius);
        
        CGFloat toOriginAngel = (originX < 0)?atan(originY/originX):(atan(originY/originX)+M_PI);
        CGFloat toOffsetAngel = (fromRadius < toRadius)?acos(offsetY/r):(M_PI-acos(offsetY/r));
        CGFloat toStartAngel = toOriginAngel + toOffsetAngel;
        CGFloat toEndAngel = toOriginAngel - toOffsetAngel;
        CGPoint toStartPoint = CGPointMake(toPoint.x+cos(toStartAngel)*toRadius, toPoint.y+sin(toStartAngel)*toRadius);
        
        CGPoint middlePoint = CGPointMake(fromPoint.x+(toPoint.x-fromPoint.x)/2, fromPoint.y+(toPoint.y-fromPoint.y)/2);
        CGFloat middleRadius = (fromRadius+toRadius)/2;
        
        CGPoint fromControlPoint = CGPointMake(middlePoint.x+sin(fromOriginAngel)*middleRadius*scale, middlePoint.y-cos(fromOriginAngel)*middleRadius*scale);
        
        CGPoint toControlPoint = CGPointMake(middlePoint.x+sin(toOriginAngel)*middleRadius*scale, middlePoint.y-cos(toOriginAngel)*middleRadius*scale);
        
        [path moveToPoint:fromStartPoint];
        
        //绘制from弧形
        [path addArcWithCenter:fromPoint radius:fromRadius startAngle:fromStartAngel endAngle:fromEndAngel clockwise:YES];
        
        //绘制from到to之间的贝塞尔曲线
        if (r > (fromRadius+toRadius)) {
            [path addQuadCurveToPoint:toStartPoint controlPoint:fromControlPoint];
        }
        
        //绘制to弧形
        [path addArcWithCenter:toPoint radius:toRadius startAngle:toStartAngel endAngle:toEndAngel clockwise:YES];
        
        //绘制to到from之间的贝塞尔曲线
        if (r > (fromRadius+toRadius)) {
            [path addQuadCurveToPoint:fromStartPoint controlPoint:toControlPoint];
        }
    }
    
    [path closePath];
    
    return path;
}

-(void)setBadgeItem:(GLBadgeItem*)item{
 
    self.textColor = item.color;
    if (item.font) {
        if (![self.font isEqual:item.font]) {
            self.font = item.font;
            _shouldUpdateSize = YES;
        }
    }
    
    
    self.style = item.style;
    if (self.style == GLBadgeStyleStringCustom) {
        self.backgroundColor = [UIColor clearColor];
    }else{
        self.backgroundColor = item.backgroundColor;
    }
    if (![self.defaultString isEqualToString:item.defaultString]) {
        self.defaultString = item.defaultString;
        _shouldUpdateSize = YES;
    }
    if (![self.defaultAttributedString isEqualToAttributedString:item.defaultAttributedString]) {
        self.defaultAttributedString = item.defaultAttributedString;
        _shouldUpdateSize = YES;
    }
    
    self.bindKeyPath = item.bindKeyPath;
    
    self.centerPosition = item.centerPosition;
    self.centerOffset = item.centerOffset;
    self.positionCustomBlock = item.positionCustomBlock;

    [self updatePosition];
}

-(void)updatePosition{
    if (!self.superview) {
        return;
    }
    switch (self.centerPosition) {
        case GLBadgeCenterPositionLB:
        {
            [self mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.centerX.mas_equalTo(0).offset(self.centerOffset.x);
                make.centerY.equalTo(self.superview).multipliedBy(2).offset(self.centerOffset.y);
            }];
//            self.center = CGPointMake(self.centerOffset.x,self.superview.frame.size.height+self.centerOffset.y);
            break;
        }
        case GLBadgeCenterPositionLT:
        {
            [self mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.centerX.mas_equalTo(0).offset(self.centerOffset.x);
                make.centerY.mas_equalTo(0).offset(self.centerOffset.y);
            }];
//            self.center = CGPointMake(self.centerOffset.x,self.centerOffset.y);
            break;
        }
        case GLBadgeCenterPositionRT:
        {
            [self mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.centerX.equalTo(self.superview).multipliedBy(2).offset(self.centerOffset.x);
                make.centerY.mas_equalTo(0).offset(self.centerOffset.y);
            }];
//            self.center = CGPointMake(self.superview.frame.size.width+self.centerOffset.x,self.centerOffset.y);
            break;
        }
        case GLBadgeCenterPositionRB:
        {
            [self mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.centerX.equalTo(self.superview).multipliedBy(2).offset(self.centerOffset.x);
                make.centerY.equalTo(self.superview).multipliedBy(2).offset(self.centerOffset.y);
            }];
//            self.center = CGPointMake(self.superview.frame.size.width+self.centerOffset.x,self.superview.frame.size.height+self.centerOffset.y);
            break;
        }
        case GLBadgeCenterPositionM:
        {
            [self mas_remakeConstraints:^(MASConstraintMaker *make) {
                make.center.equalTo(self.superview).centerOffset(self.centerOffset);
            }];
//            self.center = CGPointMake(self.superview.frame.size.width/2.0+self.centerOffset.x,self.superview.frame.size.height/2.0+self.centerOffset.y);
            break;
        }
        case GLBadgeCenterPositionCustom:{
            if (self.positionCustomBlock) {
                self.positionCustomBlock(self);
            }
            break;
        }
        default:
            break;
    }
    
}

#pragma mark- setter and getter
-(void)setBindKeyPath:(NSString *)bindKeyPath{
    if (_bindKeyPath != bindKeyPath) {
        if (_bindKeyPath) {
            [[GLBadgeCenter defaultCenter] removeObserver:self forKeyPath:_bindKeyPath];
        }
        _bindKeyPath = bindKeyPath;
    }
    if(bindKeyPath){
        [[GLBadgeCenter defaultCenter] registerObserver:self forKeyPath:bindKeyPath];
    }
    
}


@end

static char GLBadgeLabelLKey;

@implementation UIView (GLBadgeLabel)

-(void)showBadge:(NSString*)badgeStr centerOffset:(CGPoint)centerOffset badgeColor:(UIColor*)color{

    [self showBadgeStyle:0 value:badgeStr bindKeyPath:nil centerOffset:centerOffset badgeColor:color];
}

-(void)showBadgeBindKeyPath:(NSString*)keyPath centerOffset:(CGPoint)centerOffset badgeColor:(UIColor*)color{
    [self showBadgeStyle:0 value:nil bindKeyPath:keyPath centerOffset:centerOffset badgeColor:color];
}
-(void)showBadgeStyle:(GLBadgeStyle)style bindKeyPath:(NSString*)keyPath centerOffset:(CGPoint)centerOffset badgeColor:(UIColor*)color{
    [self showBadgeStyle:style value:nil bindKeyPath:keyPath centerOffset:centerOffset badgeColor:color];
}
-(void)showBadgeWithItem:(GLBadgeItem*)item{
    [self showBadgeAndConfig:^(GLBadgeLabel *abadgeLabel) {
        [abadgeLabel setBadgeItem:item];
    }];
}
-(void)showBadgeStyle:(GLBadgeStyle)style value:(NSString*)value bindKeyPath:(NSString*)keyPath centerOffset:(CGPoint)centerOffset badgeColor:(UIColor*)color{
    
    [self showBadgeAndConfig:^(GLBadgeLabel *abadgeLabel) {
        
        abadgeLabel.bindKeyPath = keyPath;
        abadgeLabel.style = style;
        [abadgeLabel updatePosition];
        abadgeLabel.backgroundColor = color;
        
        if (!keyPath) {
            if (value) {
                abadgeLabel.hidden = NO;
                abadgeLabel.text = value;
                [abadgeLabel sizeToFit];
            }else{
                abadgeLabel.text = nil;
                abadgeLabel.hidden = YES;
                
            }
        }
    }];

}

-(void)showBadgeAndConfig:(void(^)(GLBadgeLabel* badgeLabel))configBlock{
    if (!self.badgeLabel) {
        GLBadgeLabel* label = [[GLBadgeLabel alloc]init];
        
        label.font = [UIFont systemFontOfSize:12];
        self.badgeLabel = label;
        [self addSubview:self.badgeLabel];
        self.badgeLabel.centerPosition = GLBadgeCenterPositionRT;
        [self.badgeLabel updatePosition];
    }
    
    [self bringSubviewToFront:self.badgeLabel];
    
    if (configBlock) {
        configBlock(self.badgeLabel);
    }
    
}



-(void)hideBadge{
    self.badgeLabel.hidden = YES;
}

#pragma mark- setter and getter
-(GLBadgeLabel*)badgeLabel{
    return  objc_getAssociatedObject(self, &GLBadgeLabelLKey);
}

-(void)setBadgeLabel:(GLBadgeLabel *)badgeLabel{
    [self addSubview:badgeLabel];
    objc_setAssociatedObject(self, &GLBadgeLabelLKey, badgeLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end


static char GLBadgeItemKey;

@implementation UIBarItem (UIBarItem)
-(GLBadgeItem*)gl_badgeItem{
    return  objc_getAssociatedObject(self, &GLBadgeItemKey);
}
-(void)setGl_badgeItem:(GLBadgeItem *)item{
    objc_setAssociatedObject(self, &GLBadgeItemKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end


@implementation UITabBar (GLBadgeLabel)
+ (void)load{
    SEL needSwizzleSelectors[1] = {
        @selector(layoutSubviews)
    };
    
    for (int i = 0; i < 1;  i++) {
        SEL selector = needSwizzleSelectors[i];
        NSString *newSelectorStr = [[NSString stringWithFormat:@"gll_%@", NSStringFromSelector(selector)] stringByReplacingOccurrencesOfString:@"__" withString:@"_"];
        Method originMethod = class_getInstanceMethod(self, selector);
        Method swizzledMethod = class_getInstanceMethod(self, NSSelectorFromString(newSelectorStr));
        method_exchangeImplementations(originMethod, swizzledMethod);
    }
}




- (void)gll_layoutSubviews
{
    [self gll_layoutSubviews];
    CGFloat width = self.bounds.size.width / (self.items.count+1);
    
    for (UIView* sub in self.subviews) {
        
        if ([sub isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            NSInteger index = (NSInteger)sub.frame.origin.x/(NSInteger)width;
            UITabBarItem* item = [self.items objectAtIndex:index];
            
            if (item.gl_badgeItem) {
                for (UIView * v in sub.subviews) {
                    if ([v isKindOfClass:[UIImageView class]] && !v.badgeLabel) {
                        [v showBadgeAndConfig:^(GLBadgeLabel *badgeLabel) {
                            [badgeLabel setBadgeItem:item.gl_badgeItem];
                        }];
                        break;
                    }
                }
                break;
            }
        }
    }
    
}

@end
